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 v6 4/6] Add Cyclomatic complexity GCC plugin Date: Thu, 7 Apr 2016 23:16:23 +0200 [thread overview] Message-ID: <20160407231623.2158cac63a2ac2d7bbe8204f@gmail.com> (raw) In-Reply-To: <20160407231023.5f1307ffc79f0cdd880eedb7@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 | 2 + scripts/gcc-plugins/Makefile | 4 ++ scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 7c12571..ddf29b4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -366,6 +366,18 @@ menuconfig GCC_PLUGINS GCC plugins are loadable modules that provide extra features to the compiler. They are useful for runtime instrumentation and static analysis. +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 b981b65..34ad58b 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -2,6 +2,8 @@ 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)) ifeq ($(PLUGINCC),) diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index b2d64af..31c72bf 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -12,4 +12,8 @@ endif export GCCPLUGINS_DIR HOSTLIBS +$(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) := cyc_complexity_plugin.so + always := $($(HOSTLIBS)-y) + +cyc_complexity_plugin-objs := cyc_complexity_plugin.o 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.4.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 v6 4/6] Add Cyclomatic complexity GCC plugin Date: Thu, 7 Apr 2016 23:16:23 +0200 [thread overview] Message-ID: <20160407231623.2158cac63a2ac2d7bbe8204f@gmail.com> (raw) In-Reply-To: <20160407231023.5f1307ffc79f0cdd880eedb7@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 | 2 + scripts/gcc-plugins/Makefile | 4 ++ scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 7c12571..ddf29b4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -366,6 +366,18 @@ menuconfig GCC_PLUGINS GCC plugins are loadable modules that provide extra features to the compiler. They are useful for runtime instrumentation and static analysis. +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 b981b65..34ad58b 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -2,6 +2,8 @@ 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)) ifeq ($(PLUGINCC),) diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index b2d64af..31c72bf 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -12,4 +12,8 @@ endif export GCCPLUGINS_DIR HOSTLIBS +$(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) := cyc_complexity_plugin.so + always := $($(HOSTLIBS)-y) + +cyc_complexity_plugin-objs := cyc_complexity_plugin.o 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.4.1
next prev parent reply other threads:[~2016-04-07 21:18 UTC|newest] Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-04-07 21:10 [PATCH v6 0/6] Introduce GCC plugin infrastructure Emese Revfy 2016-04-07 21:10 ` [kernel-hardening] " Emese Revfy 2016-04-07 21:11 ` [PATCH v6 1/6] Shared library support Emese Revfy 2016-04-07 21:11 ` [kernel-hardening] " Emese Revfy 2016-04-07 21:13 ` [PATCH v6 2/6] GCC plugin infrastructure Emese Revfy 2016-04-07 21:13 ` [kernel-hardening] " Emese Revfy 2016-04-13 2:35 ` Masahiro Yamada 2016-04-13 2:35 ` [kernel-hardening] " Masahiro Yamada 2016-04-21 16:55 ` Kees Cook 2016-04-21 16:55 ` [kernel-hardening] " Kees Cook 2016-04-21 16:55 ` Kees Cook 2016-04-07 21:15 ` [PATCH v6 3/6] The GCC plugin infrastructure supports the arm and arm64 architectures too Emese Revfy 2016-04-07 21:15 ` [kernel-hardening] " Emese Revfy 2016-04-07 21:16 ` Emese Revfy [this message] 2016-04-07 21:16 ` [kernel-hardening] [PATCH v6 4/6] Add Cyclomatic complexity GCC plugin Emese Revfy 2016-04-07 21:17 ` [PATCH v6 5/6] Documentation for the GCC plugin infrastructure Emese Revfy 2016-04-07 21:17 ` [kernel-hardening] " Emese Revfy 2016-04-07 21:19 ` [PATCH v6 6/6] Add sancov plugin Emese Revfy 2016-04-07 21:19 ` [kernel-hardening] " Emese Revfy 2016-04-12 17:46 ` [PATCH v6 0/6] Introduce GCC plugin infrastructure David Brown 2016-04-12 17:46 ` [kernel-hardening] " David Brown 2016-04-12 18:27 ` Kees Cook 2016-04-12 18:27 ` [kernel-hardening] " Kees Cook 2016-04-12 18:27 ` Kees Cook 2016-04-12 18:41 ` David Brown 2016-04-12 18:41 ` [kernel-hardening] " David Brown 2016-04-12 18:41 ` David Brown 2016-04-12 19:46 ` Kees Cook 2016-04-12 19:46 ` [kernel-hardening] " Kees Cook 2016-04-12 19:46 ` Kees Cook 2016-04-12 21:26 ` PaX Team 2016-04-12 21:26 ` [kernel-hardening] " PaX Team 2016-04-12 21:26 ` PaX Team 2016-04-12 18:52 ` Emese Revfy 2016-04-12 18:52 ` [kernel-hardening] " Emese Revfy 2016-04-12 18:52 ` Emese Revfy 2016-04-12 19:47 ` Kees Cook 2016-04-12 19:47 ` [kernel-hardening] " Kees Cook 2016-04-12 19:47 ` Kees Cook
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=20160407231623.2158cac63a2ac2d7bbe8204f@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: linkBe 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.