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]

Add GPL compatibility check for plugins


On request from the FSF, I am adding this check.

When a plugin is loaded, the compiler checks whether the symbol
plugin_is_GPL_compatible exists in the loaded shared object.

The presence of this symbol asserts that the loaded plugin has
been licenced under a GPL-compatible license.  If the symbol does
not exist, the compiler exits with the message:

fatal error: plugin <name> is not licensed under a GPL-compatible license

Tested on x86_64.  Committed to mainline.



	* doc/plugins.texi: Document plugin_is_GPL_compatible.
	* plugin.c (str_license): Declare.
	(try_init_one_plugin): Assert that the symbol
	'plugin_is_GPL_compatible' exists.

testsuite/ChangeLog

	* gcc.dg/plugin/selfassign.c: Declare plugin_is_GPL_compatible.
	* gcc.dg/plugin/ggcplug.c: Likewise.
	* gcc.dg/plugin/one_time_plugin.c: Likewise.
	* g++.dg/plugin/selfassign.c: Likewise.
	* g++.dg/plugin/attribute_plugin.c: Likewise.
	* g++.dg/plugin/dumb_plugin.c: Likewise.

Index: doc/plugins.texi
===================================================================
--- doc/plugins.texi	(revision 148666)
+++ doc/plugins.texi	(working copy)
@@ -32,6 +32,26 @@ address of the callback function that wi
 
 The header @file{gcc-plugin.h} must be the first gcc header to be included.
 
+@subsection Plugin license check
+
+Every plugin should define the global symbol @code{plugin_is_GPL_compatible}
+to assert that it has been licensed under a GPL-compatible license.
+If this symbol does not exist, the compiler will emit a fatal error
+and exit with the error message:
+
+@smallexample
+fatal error: plugin <name> is not licensed under a GPL-compatible license
+<name>: undefined symbol: plugin_is_GPL_compatible
+compilation terminated
+@end smallexample
+
+The type of the symbol is irrelevant.  The compiler merely asserts that
+it exists in the global scope.  Something like this is enough:
+
+@smallexample
+int plugin_is_GPL_compatible;
+@end smallexample
+
 @subsection Plugin initialization
 
 Every plugin should export a function called @code{plugin_init} that
Index: testsuite/gcc.dg/plugin/selfassign.c
===================================================================
--- testsuite/gcc.dg/plugin/selfassign.c	(revision 148666)
+++ testsuite/gcc.dg/plugin/selfassign.c	(working copy)
@@ -15,6 +15,8 @@
 #include "intl.h"
 
 
+int plugin_is_GPL_compatible;
+
 /* Indicate whether to check overloaded operator '=', which is performed by
    default. To disable it, use -fplugin-arg-NAME-no-check-operator-eq.  */
 bool check_operator_eq = true;
Index: testsuite/gcc.dg/plugin/ggcplug.c
===================================================================
--- testsuite/gcc.dg/plugin/ggcplug.c	(revision 148666)
+++ testsuite/gcc.dg/plugin/ggcplug.c	(working copy)
@@ -13,7 +13,7 @@
 #include "intl.h"
 #include "gcc-plugin.h"
 
-
+int plugin_is_GPL_compatible;
 
 /* our callback is the same for all PLUGIN_GGC_START,
    PLUGIN_GGC_MARKING, PLUGIN_GGC_END events; it just increments the
Index: testsuite/gcc.dg/plugin/one_time_plugin.c
===================================================================
--- testsuite/gcc.dg/plugin/one_time_plugin.c	(revision 148666)
+++ testsuite/gcc.dg/plugin/one_time_plugin.c	(working copy)
@@ -9,6 +9,8 @@
 #include "tree-pass.h"
 #include "intl.h"
 
+int plugin_is_GPL_compatible;
+
 static bool one_pass_gate (void)
 {
   return true;
Index: testsuite/g++.dg/plugin/selfassign.c
===================================================================
--- testsuite/g++.dg/plugin/selfassign.c	(revision 148666)
+++ testsuite/g++.dg/plugin/selfassign.c	(working copy)
@@ -14,6 +14,7 @@
 #include "tree-pass.h"
 #include "intl.h"
 
+int plugin_is_GPL_compatible;
 
 /* Indicate whether to check overloaded operator '=', which is performed by
    default. To disable it, use -fplugin-arg-NAME-no-check-operator-eq.  */
Index: testsuite/g++.dg/plugin/attribute_plugin.c
===================================================================
--- testsuite/g++.dg/plugin/attribute_plugin.c	(revision 148666)
+++ testsuite/g++.dg/plugin/attribute_plugin.c	(working copy)
@@ -9,6 +9,8 @@
 #include "tree-pass.h"
 #include "intl.h"
 
+int plugin_is_GPL_compatible;
+
 /* Attribute handler callback */
 
 static tree
Index: testsuite/g++.dg/plugin/dumb_plugin.c
===================================================================
--- testsuite/g++.dg/plugin/dumb_plugin.c	(revision 148666)
+++ testsuite/g++.dg/plugin/dumb_plugin.c	(working copy)
@@ -10,6 +10,7 @@
 #include "tree-pass.h"
 #include "intl.h"
 
+int plugin_is_GPL_compatible;
 
 /* Callback function to invoke after GCC finishes parsing a struct.  */
 
Index: plugin.c
===================================================================
--- plugin.c	(revision 148666)
+++ plugin.c	(working copy)
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3.  
 
 /* If plugin support is not enabled, do not try to execute any code
    that may reference libdl.  The generic code is still compiled in to
-   avoid including to many conditional compilation paths in the rest
+   avoid including too many conditional compilation paths in the rest
    of the compiler.  */
 #ifdef ENABLE_PLUGIN
 #include <dlfcn.h>
@@ -95,6 +95,10 @@ static struct pass_list_node *prev_added
 /* Each plugin should define an initialization function with exactly
    this name.  */
 static const char *str_plugin_init_func_name = "plugin_init";
+
+/* Each plugin should define this symbol to assert that it is
+   distributed under a GPL-compatible license.  */
+static const char *str_license = "plugin_is_GPL_compatible";
 #endif
 
 /* Helper function for the hash table that compares the base_name of the
@@ -595,6 +599,11 @@ try_init_one_plugin (struct plugin_name_
   /* Clear any existing error.  */
   dlerror ();
 
+  /* Check the plugin license.  */
+  if (dlsym (dl_handle, str_license) == NULL)
+    fatal_error ("plugin %s is not licensed under a GPL-compatible license\n"
+		 "%s", plugin->full_name, dlerror ());
+
   PTR_UNION_AS_VOID_PTR (plugin_init_union) =
       dlsym (dl_handle, str_plugin_init_func_name);
   plugin_init = PTR_UNION_AS_CAST_PTR (plugin_init_union);


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