Message ID | 20190816122403.14994-10-raphael.gault@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | objtool: Add support for arm64 | expand |
On Fri, Aug 16, 2019 at 01:23:54PM +0100, Raphael Gault wrote: > This plugins comes into play before the final 2 RTL passes of GCC and "plugin" > detects switch-tables that are to be outputed in the ELF and writes > information in an "objtool_data" section which will be used by objtool. The section should probably have a ".discard" prefix (.discard.objtool_data) so it gets discarded at link time. Also, "objtool_data" is a bit generic. How about ".discard.switch_tables" or something. > > Signed-off-by: Raphael Gault <raphael.gault@arm.com> > --- > scripts/Makefile.gcc-plugins | 2 + > scripts/gcc-plugins/Kconfig | 9 +++ > .../arm64_switch_table_detection_plugin.c | 58 +++++++++++++++++++ > 3 files changed, 69 insertions(+) > create mode 100644 scripts/gcc-plugins/arm64_switch_table_detection_plugin.c > > diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins > index 5f7df50cfe7a..a56736df9dc2 100644 > --- a/scripts/Makefile.gcc-plugins > +++ b/scripts/Makefile.gcc-plugins > @@ -44,6 +44,8 @@ ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK > endif > export DISABLE_ARM_SSP_PER_TASK_PLUGIN > > +gcc-plugin-$(CONFIG_GCC_PLUGIN_SWITCH_TABLES) += arm64_switch_table_detection_plugin.so > + > # All the plugin CFLAGS are collected here in case a build target needs to > # filter them out of the KBUILD_CFLAGS. > GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) > diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig > index d33de0b9f4f5..1daeffb55dce 100644 > --- a/scripts/gcc-plugins/Kconfig > +++ b/scripts/gcc-plugins/Kconfig > @@ -113,4 +113,13 @@ config GCC_PLUGIN_ARM_SSP_PER_TASK > bool > depends on GCC_PLUGINS && ARM > > +config GCC_PLUGIN_SWITCH_TABLES > + bool "GCC Plugin: Identify switch tables at compile time" > + default y > + depends on STACK_VALIDATION && ARM64 > + help > + Plugin to identify switch tables generated at compile time and store > + them in a .objtool_data section. Objtool will then use that section > + to analyse the different execution path of the switch table. This isn't something you want to ask the user about, as objtool for arm64 requires it. For the same reason, instead of GCC_PLUGIN_SWITCH_TABLES depending on STACK_VALIDATION, arm64 HAVE_STACK_VALIDATION should depend on GCC_PLUGIN_SWITCH_TABLES.
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 5f7df50cfe7a..a56736df9dc2 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -44,6 +44,8 @@ ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK endif export DISABLE_ARM_SSP_PER_TASK_PLUGIN +gcc-plugin-$(CONFIG_GCC_PLUGIN_SWITCH_TABLES) += arm64_switch_table_detection_plugin.so + # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index d33de0b9f4f5..1daeffb55dce 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -113,4 +113,13 @@ config GCC_PLUGIN_ARM_SSP_PER_TASK bool depends on GCC_PLUGINS && ARM +config GCC_PLUGIN_SWITCH_TABLES + bool "GCC Plugin: Identify switch tables at compile time" + default y + depends on STACK_VALIDATION && ARM64 + help + Plugin to identify switch tables generated at compile time and store + them in a .objtool_data section. Objtool will then use that section + to analyse the different execution path of the switch table. + endmenu diff --git a/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c b/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c new file mode 100644 index 000000000000..d7f0e13910d5 --- /dev/null +++ b/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <stdio.h> +#include "gcc-common.h" + +__visible int plugin_is_GPL_compatible; + +static unsigned int arm64_switchtbl_rtl_execute(void) +{ + rtx_insn *insn; + rtx_insn *labelp = NULL; + rtx_jump_table_data *tablep = NULL; + section *sec = get_section(".objtool_data", SECTION_STRINGS, NULL); + section *curr_sec = current_function_section(); + + for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) { + /* + * Find a tablejump_p INSN (using a dispatch table) + */ + if (!tablejump_p(insn, &labelp, &tablep)) + continue; + + if (labelp && tablep) { + switch_to_section(sec); + assemble_integer_with_op(".quad ", gen_rtx_LABEL_REF(Pmode, labelp)); + assemble_integer_with_op(".quad ", GEN_INT(GET_NUM_ELEM(tablep->get_labels()))); + assemble_integer_with_op(".quad ", GEN_INT(ADDR_DIFF_VEC_FLAGS(tablep).offset_unsigned)); + switch_to_section(curr_sec); + } + } + return 0; +} + +#define PASS_NAME arm64_switchtbl_rtl + +#define NO_GATE +#include "gcc-generate-rtl-pass.h" + +__visible int plugin_init(struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + int tso = 0; + int i; + + if (!plugin_default_version_check(version, &gcc_version)) { + error(G_("incompatible gcc/plugin versions")); + return 1; + } + + PASS_INFO(arm64_switchtbl_rtl, "outof_cfglayout", 1, + PASS_POS_INSERT_AFTER); + + register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, + NULL, &arm64_switchtbl_rtl_pass_info); + + return 0; +}
This plugins comes into play before the final 2 RTL passes of GCC and detects switch-tables that are to be outputed in the ELF and writes information in an "objtool_data" section which will be used by objtool. Signed-off-by: Raphael Gault <raphael.gault@arm.com> --- scripts/Makefile.gcc-plugins | 2 + scripts/gcc-plugins/Kconfig | 9 +++ .../arm64_switch_table_detection_plugin.c | 58 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 scripts/gcc-plugins/arm64_switch_table_detection_plugin.c