All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emese Revfy <re.emese@gmail.com>
To: linux-kbuild@vger.kernel.org
Cc: pageexec@freemail.hu, spender@grsecurity.net,
	kernel-hardening@lists.openwall.com, mmarek@suse.com,
	keescook@chromium.org, linux@rasmusvillemoes.dk,
	fengguang.wu@intel.com, dvyukov@google.com,
	linux-kernel@vger.kernel.org, david.brown@linaro.org,
	yamada.masahiro@socionext.com
Subject: [PATCH v9 3/4] Add Cyclomatic complexity GCC plugin
Date: Tue, 24 May 2016 00:10:35 +0200	[thread overview]
Message-ID: <20160524001035.081cbf822a62b274ad945dc1@gmail.com> (raw)
In-Reply-To: <20160524000719.b456ed0cd2aafacb4e53f177@gmail.com>

Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where
E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy <re.emese@gmail.com>
---
 arch/Kconfig                                | 12 +++++
 scripts/Makefile.gcc-plugins                |  1 +
 scripts/gcc-plugins/Makefile                |  1 +
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 2821cfe..74f0d63 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -372,6 +372,18 @@ menuconfig GCC_PLUGINS
 
 	  See Documentation/gcc-plugins.txt for details.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+	bool "Compute the cyclomatic complexity of a function"
+	depends on GCC_PLUGINS
+	help
+	  The complexity M of a function's control flow graph is defined as:
+	   M = E - N + 2P
+	  where
+
+	  E = the number of edges
+	  N = the number of nodes
+	  P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
 	bool
 	help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index bcc373d..b4a189c 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,7 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)	+= cyc_complexity_plugin.so
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
 
   export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index a4c9341..c60ba4b 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -17,4 +17,5 @@ export GCCPLUGINS_DIR HOSTLIBS
 $(HOSTLIBS)-y := $(GCC_PLUGIN)
 always := $($(HOSTLIBS)-y)
 
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
 clean-files += *.so
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 0000000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+	.version	= "20160225",
+	.help		= "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+	int complexity;
+	expanded_location xloc;
+
+	/* M = E - N + 2P */
+	complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+	xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+	fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+		xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+	return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
+{
+	const char * const plugin_name = plugin_info->base_name;
+	struct register_pass_info cyc_complexity_pass_info;
+
+	cyc_complexity_pass_info.pass				= make_cyc_complexity_pass();
+	cyc_complexity_pass_info.reference_pass_name		= "ssa";
+	cyc_complexity_pass_info.ref_pass_instance_number	= 1;
+	cyc_complexity_pass_info.pos_op				= PASS_POS_INSERT_AFTER;
+
+	if (!plugin_default_version_check(version, &gcc_version)) {
+		error(G_("incompatible gcc/plugin versions"));
+		return 1;
+	}
+
+	register_callback(plugin_name, PLUGIN_INFO, NULL,
+				&cyc_complexity_plugin_info);
+	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+				&cyc_complexity_pass_info);
+
+	return 0;
+}
-- 
2.8.1

WARNING: multiple messages have this Message-ID (diff)
From: Emese Revfy <re.emese@gmail.com>
To: linux-kbuild@vger.kernel.org
Cc: pageexec@freemail.hu, spender@grsecurity.net,
	kernel-hardening@lists.openwall.com, mmarek@suse.com,
	keescook@chromium.org, linux@rasmusvillemoes.dk,
	fengguang.wu@intel.com, dvyukov@google.com,
	linux-kernel@vger.kernel.org, david.brown@linaro.org,
	yamada.masahiro@socionext.com
Subject: [kernel-hardening] [PATCH v9 3/4] Add Cyclomatic complexity GCC plugin
Date: Tue, 24 May 2016 00:10:35 +0200	[thread overview]
Message-ID: <20160524001035.081cbf822a62b274ad945dc1@gmail.com> (raw)
In-Reply-To: <20160524000719.b456ed0cd2aafacb4e53f177@gmail.com>

Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where
E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy <re.emese@gmail.com>
---
 arch/Kconfig                                | 12 +++++
 scripts/Makefile.gcc-plugins                |  1 +
 scripts/gcc-plugins/Makefile                |  1 +
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 2821cfe..74f0d63 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -372,6 +372,18 @@ menuconfig GCC_PLUGINS
 
 	  See Documentation/gcc-plugins.txt for details.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+	bool "Compute the cyclomatic complexity of a function"
+	depends on GCC_PLUGINS
+	help
+	  The complexity M of a function's control flow graph is defined as:
+	   M = E - N + 2P
+	  where
+
+	  E = the number of edges
+	  N = the number of nodes
+	  P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
 	bool
 	help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index bcc373d..b4a189c 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,7 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)	+= cyc_complexity_plugin.so
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
 
   export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index a4c9341..c60ba4b 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -17,4 +17,5 @@ export GCCPLUGINS_DIR HOSTLIBS
 $(HOSTLIBS)-y := $(GCC_PLUGIN)
 always := $($(HOSTLIBS)-y)
 
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
 clean-files += *.so
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 0000000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+	.version	= "20160225",
+	.help		= "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+	int complexity;
+	expanded_location xloc;
+
+	/* M = E - N + 2P */
+	complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+	xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+	fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+		xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+	return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
+{
+	const char * const plugin_name = plugin_info->base_name;
+	struct register_pass_info cyc_complexity_pass_info;
+
+	cyc_complexity_pass_info.pass				= make_cyc_complexity_pass();
+	cyc_complexity_pass_info.reference_pass_name		= "ssa";
+	cyc_complexity_pass_info.ref_pass_instance_number	= 1;
+	cyc_complexity_pass_info.pos_op				= PASS_POS_INSERT_AFTER;
+
+	if (!plugin_default_version_check(version, &gcc_version)) {
+		error(G_("incompatible gcc/plugin versions"));
+		return 1;
+	}
+
+	register_callback(plugin_name, PLUGIN_INFO, NULL,
+				&cyc_complexity_plugin_info);
+	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+				&cyc_complexity_pass_info);
+
+	return 0;
+}
-- 
2.8.1

  parent reply	other threads:[~2016-05-23 22:03 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-23 22:07 [PATCH v9 0/4] Introduce GCC plugin infrastructure Emese Revfy
2016-05-23 22:07 ` [kernel-hardening] " Emese Revfy
2016-05-23 22:08 ` [PATCH v9 1/4] Shared library support Emese Revfy
2016-05-23 22:08   ` [kernel-hardening] " Emese Revfy
2016-05-23 22:09 ` [PATCH v9 2/4] GCC plugin infrastructure Emese Revfy
2016-05-23 22:09   ` [kernel-hardening] " Emese Revfy
2016-05-23 22:10 ` Emese Revfy [this message]
2016-05-23 22:10   ` [kernel-hardening] [PATCH v9 3/4] Add Cyclomatic complexity GCC plugin Emese Revfy
2016-06-14 19:29   ` Laura Abbott
2016-06-14 19:29     ` [kernel-hardening] " Laura Abbott
2016-06-14 22:33     ` Emese Revfy
2016-06-14 22:33       ` [kernel-hardening] " Emese Revfy
2016-06-15 20:53     ` Emese Revfy
2016-06-15 20:53       ` [kernel-hardening] " Emese Revfy
2016-06-15 22:41       ` Kees Cook
2016-06-15 22:41         ` [kernel-hardening] " Kees Cook
2016-06-15 22:41         ` Kees Cook
2016-05-23 22:11 ` [PATCH v9 4/4] Add sancov plugin Emese Revfy
2016-05-23 22:11   ` [kernel-hardening] " Emese Revfy
2016-05-24 17:04 ` [PATCH v9 0/4] Introduce GCC plugin infrastructure Kees Cook
2016-05-24 17:04   ` [kernel-hardening] " Kees Cook
2016-05-24 17:04   ` Kees Cook
2016-05-25 10:46   ` Michal Marek
2016-05-25 10:46     ` [kernel-hardening] " Michal Marek
2016-05-25 10:46     ` Michal Marek
2016-05-25 17:12     ` Kees Cook
2016-05-25 17:12       ` [kernel-hardening] " Kees Cook
2016-05-25 17:12       ` Kees Cook
2016-06-07 20:58       ` Michal Marek
2016-06-07 20:58         ` [kernel-hardening] " Michal Marek
2016-06-07 20:58         ` Michal Marek
2016-06-07 20:59         ` Kees Cook
2016-06-07 20:59           ` [kernel-hardening] " Kees Cook
2016-06-07 20:59           ` Kees Cook
2016-06-07 21:59           ` Emese Revfy
2016-06-07 21:59             ` [kernel-hardening] " Emese Revfy
2016-06-07 21:59             ` Emese Revfy
2016-06-07 21:58             ` Kees Cook
2016-06-07 21:58               ` [kernel-hardening] " Kees Cook
2016-06-07 21:58               ` Kees Cook
2016-06-08  6:59               ` Michal Marek
2016-06-08  6:59                 ` [kernel-hardening] " Michal Marek
2016-06-08  6:59                 ` Michal Marek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160524001035.081cbf822a62b274ad945dc1@gmail.com \
    --to=re.emese@gmail.com \
    --cc=david.brown@linaro.org \
    --cc=dvyukov@google.com \
    --cc=fengguang.wu@intel.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@rasmusvillemoes.dk \
    --cc=mmarek@suse.com \
    --cc=pageexec@freemail.hu \
    --cc=spender@grsecurity.net \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.