From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Emese Revfy <re.emese@gmail.com>
Cc: linux-kbuild@vger.kernel.org, pageexec@freemail.hu,
spender@grsecurity.net, kernel-hardening@lists.openwall.com,
mmarek@suse.com, keescook@chromium.org
Subject: [kernel-hardening] Re: [PATCH 2/3] Add Cyclomatic complexity GCC plugin
Date: Mon, 08 Feb 2016 00:05:15 +0100 [thread overview]
Message-ID: <87mvrcdsus.fsf@rasmusvillemoes.dk> (raw)
In-Reply-To: <20160207223140.830691e83ab579f46f991410@gmail.com> (Emese Revfy's message of "Sun, 7 Feb 2016 22:31:40 +0100")
On Sun, Feb 07 2016, Emese Revfy <re.emese@gmail.com> wrote:
> 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).
>
> ---
> Makefile | 6 +-
> arch/Kconfig | 16 +++++
> tools/gcc/Makefile | 4 ++
> tools/gcc/cyc_complexity_plugin.c | 120 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 145 insertions(+), 1 deletion(-)
> create mode 100644 tools/gcc/cyc_complexity_plugin.c
>
> diff --git a/Makefile b/Makefile
> index 96ce015..9f76c26 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -628,7 +628,11 @@ else
> PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)")
> endif
> ifneq ($(PLUGINCC),)
> -export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS
> +ifdef CONFIG_GCC_PLUGIN_CYC_COMPLEXITY
> +GCC_PLUGIN_CYC_COMPLEXITY_CFLAGS := -fplugin=$(objtree)/tools/gcc/cyc_complexity_plugin.so -DGCC_PLUGIN_CYC_COMPLEXITY
> +endif
> +GCC_PLUGINS_CFLAGS := $(GCC_PLUGIN_CYC_COMPLEXITY_CFLAGS)
> +export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS GCC_PLUGIN_CYC_COMPLEXITY
Hm, when the number of plugins grow, I think it'll be somewhat ugly
having all this in the main makefile. Can't all the plugin-related stuff
live in a separate makefile? The same goes for the Kconfig part.
Also, I think the compile command lines are already complicated enough
(I sometimes use V=1 to see what's going on), so I think it's better
that the plugins that need to make themselves known do so "from within"
gcc; something like
static void define_feature_macro(void __unused *event_data, void __unused *data)
{
cpp_define(parse_in, "HAVE_ATTRIBUTE_FOOBAR");
}
...
register_callback(plugin_name, PLUGIN_START_UNIT, &define_feature_macro, NULL);
> +
> +#include "gcc-common.h"
> +
> +int plugin_is_GPL_compatible;
> +
> +static struct plugin_info cyc_complexity_plugin_info = {
> + .version = "20150523",
> + .help = "Cyclomatic Complexity\n",
> +};
> +
> +static unsigned int handle_function(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;
> +}
> +
> +#if BUILDING_GCC_VERSION >= 4009
> +namespace {
> +static const struct pass_data cyc_complexity_pass_data = {
> +#else
> +static struct gimple_opt_pass cyc_complexity_pass = {
> + .pass = {
> +#endif
> + .type = GIMPLE_PASS,
> + .name = "cyc_complexity",
> +#if BUILDING_GCC_VERSION >= 4008
> + .optinfo_flags = OPTGROUP_NONE,
> +#endif
> +#if BUILDING_GCC_VERSION >= 5000
> +#elif BUILDING_GCC_VERSION >= 4009
> + .has_gate = false,
> + .has_execute = true,
> +#else
> + .gate = NULL,
> + .execute = handle_function,
> + .sub = NULL,
> + .next = NULL,
> + .static_pass_number = 0,
> +#endif
> + .tv_id = TV_NONE,
> + .properties_required = 0,
> + .properties_provided = 0,
> + .properties_destroyed = 0,
> + .todo_flags_start = 0,
> + .todo_flags_finish = TODO_dump_func
> +#if BUILDING_GCC_VERSION < 4009
> + }
> +#endif
> +};
> +
This is really yucky. Is there any way a mere mortal could figure out
how to write this? Or could the compatibility layer provide some utility
macros that would take care of the boilerplate?
Rasmus
WARNING: multiple messages have this Message-ID (diff)
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Emese Revfy <re.emese@gmail.com>
Cc: linux-kbuild@vger.kernel.org, pageexec@freemail.hu,
spender@grsecurity.net, kernel-hardening@lists.openwall.com,
mmarek@suse.com, keescook@chromium.org
Subject: Re: [PATCH 2/3] Add Cyclomatic complexity GCC plugin
Date: Mon, 08 Feb 2016 00:05:15 +0100 [thread overview]
Message-ID: <87mvrcdsus.fsf@rasmusvillemoes.dk> (raw)
In-Reply-To: <20160207223140.830691e83ab579f46f991410@gmail.com> (Emese Revfy's message of "Sun, 7 Feb 2016 22:31:40 +0100")
On Sun, Feb 07 2016, Emese Revfy <re.emese@gmail.com> wrote:
> 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).
>
> ---
> Makefile | 6 +-
> arch/Kconfig | 16 +++++
> tools/gcc/Makefile | 4 ++
> tools/gcc/cyc_complexity_plugin.c | 120 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 145 insertions(+), 1 deletion(-)
> create mode 100644 tools/gcc/cyc_complexity_plugin.c
>
> diff --git a/Makefile b/Makefile
> index 96ce015..9f76c26 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -628,7 +628,11 @@ else
> PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)")
> endif
> ifneq ($(PLUGINCC),)
> -export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS
> +ifdef CONFIG_GCC_PLUGIN_CYC_COMPLEXITY
> +GCC_PLUGIN_CYC_COMPLEXITY_CFLAGS := -fplugin=$(objtree)/tools/gcc/cyc_complexity_plugin.so -DGCC_PLUGIN_CYC_COMPLEXITY
> +endif
> +GCC_PLUGINS_CFLAGS := $(GCC_PLUGIN_CYC_COMPLEXITY_CFLAGS)
> +export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS GCC_PLUGIN_CYC_COMPLEXITY
Hm, when the number of plugins grow, I think it'll be somewhat ugly
having all this in the main makefile. Can't all the plugin-related stuff
live in a separate makefile? The same goes for the Kconfig part.
Also, I think the compile command lines are already complicated enough
(I sometimes use V=1 to see what's going on), so I think it's better
that the plugins that need to make themselves known do so "from within"
gcc; something like
static void define_feature_macro(void __unused *event_data, void __unused *data)
{
cpp_define(parse_in, "HAVE_ATTRIBUTE_FOOBAR");
}
...
register_callback(plugin_name, PLUGIN_START_UNIT, &define_feature_macro, NULL);
> +
> +#include "gcc-common.h"
> +
> +int plugin_is_GPL_compatible;
> +
> +static struct plugin_info cyc_complexity_plugin_info = {
> + .version = "20150523",
> + .help = "Cyclomatic Complexity\n",
> +};
> +
> +static unsigned int handle_function(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;
> +}
> +
> +#if BUILDING_GCC_VERSION >= 4009
> +namespace {
> +static const struct pass_data cyc_complexity_pass_data = {
> +#else
> +static struct gimple_opt_pass cyc_complexity_pass = {
> + .pass = {
> +#endif
> + .type = GIMPLE_PASS,
> + .name = "cyc_complexity",
> +#if BUILDING_GCC_VERSION >= 4008
> + .optinfo_flags = OPTGROUP_NONE,
> +#endif
> +#if BUILDING_GCC_VERSION >= 5000
> +#elif BUILDING_GCC_VERSION >= 4009
> + .has_gate = false,
> + .has_execute = true,
> +#else
> + .gate = NULL,
> + .execute = handle_function,
> + .sub = NULL,
> + .next = NULL,
> + .static_pass_number = 0,
> +#endif
> + .tv_id = TV_NONE,
> + .properties_required = 0,
> + .properties_provided = 0,
> + .properties_destroyed = 0,
> + .todo_flags_start = 0,
> + .todo_flags_finish = TODO_dump_func
> +#if BUILDING_GCC_VERSION < 4009
> + }
> +#endif
> +};
> +
This is really yucky. Is there any way a mere mortal could figure out
how to write this? Or could the compatibility layer provide some utility
macros that would take care of the boilerplate?
Rasmus
next prev parent reply other threads:[~2016-02-07 23:05 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-07 21:27 [kernel-hardening] [PATCH 0/3] Introduce GCC plugin infrastructure Emese Revfy
2016-02-07 21:27 ` Emese Revfy
2016-02-07 21:28 ` [kernel-hardening] [PATCH 1/3] " Emese Revfy
2016-02-07 21:28 ` Emese Revfy
2016-02-08 20:28 ` [kernel-hardening] " Michal Marek
2016-02-08 20:28 ` Michal Marek
2016-02-08 21:31 ` [kernel-hardening] " Emese Revfy
2016-02-08 21:31 ` Emese Revfy
2016-02-07 21:31 ` [kernel-hardening] [PATCH 2/3] Add Cyclomatic complexity GCC plugin Emese Revfy
2016-02-07 21:31 ` Emese Revfy
2016-02-07 23:05 ` Rasmus Villemoes [this message]
2016-02-07 23:05 ` Rasmus Villemoes
2016-02-08 21:20 ` [kernel-hardening] " Emese Revfy
2016-02-08 21:20 ` Emese Revfy
2016-02-09 4:23 ` [kernel-hardening] " Kees Cook
2016-02-09 4:23 ` Kees Cook
2016-02-09 18:55 ` [kernel-hardening] " Emese Revfy
2016-02-09 18:55 ` Emese Revfy
2016-02-07 21:32 ` [kernel-hardening] [PATCH 3/3] Documentation for the GCC plugin infrastructure Emese Revfy
2016-02-07 21:32 ` Emese Revfy
2016-02-09 4:27 ` [kernel-hardening] " Kees Cook
2016-02-09 4:27 ` Kees Cook
2016-02-09 19:14 ` [kernel-hardening] " Emese Revfy
2016-02-09 19:14 ` Emese Revfy
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=87mvrcdsus.fsf@rasmusvillemoes.dk \
--to=linux@rasmusvillemoes.dk \
--cc=keescook@chromium.org \
--cc=kernel-hardening@lists.openwall.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=mmarek@suse.com \
--cc=pageexec@freemail.hu \
--cc=re.emese@gmail.com \
--cc=spender@grsecurity.net \
/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.