[Adding Josh in CC]
> On Thu, Sep 12, 2024 at 06:09:53PM +0200, Jose E. Marchesi via Gcc wrote: >> - "noreturn" and jump tables run-time hints >> >> It has been expressed on the kernel side the desire of having the C >> compiler >> emit run-time hints marking functions that are not supposed to return and >> also to provide annotations on jump tables. This is for the benefit of >> objtool in arm64, see references below. >> >> Goal of the discussion: >> >> Collect and assess the requirements of these features, discuss their >> pertinence and the way it could be best implemented. The outcome of the >> discussion will then be used to continue the discussion with the clang/llvm >> and kernel hackers at LPC. >> >> References: >> >> https://lore.kernel.org/linux-arm-kernel/yylmhuxtuanza...@hirez.programming.kicks-ass.net/ > > What I was suggesting is something like (completely untested, GPL v2.0+ in > case you'd like to use anything from that): > #include "gcc-common.h" > > __visible int plugin_is_GPL_compatible; > > static struct plugin_info mark_noreturn_plugin_info = { > .version = PLUGIN_VERSION, > .help = "mark noreturn plugin\n", > }; > > static unsigned int mark_noreturn_execute(void) > { > if (flags_from_decl_or_type(current_function_decl) & ECF_NORETURN) { > const char *name = > IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(current_function_decl)); > name = targetm.strip_name_encoding(name); > name = concat("__noreturn_function.", name, NULL); > tree decl = build_decl(UNKNOWN_LOCATION, FUNCTION_DECL, > get_identifier(name), > TREE_TYPE(current_function_decl)); > DECL_ARTIFICIAL(decl) = 1; > TREE_PUBLIC(decl) = 0; > DECL_WEAK(decl) = DECL_WEAK(current_function_decl); > assemble_alias(current_function_decl, decl); > } > return 0; > } > > #define PASS_NAME mark_noreturn > > #define NO_GATE > > #include "gcc-generate-gimple-pass.h" > > __visible int plugin_init(struct plugin_name_args *plugin_info, struct > plugin_gcc_version *version) > { > int i; > const char * const plugin_name = plugin_info->base_name; > const int argc = plugin_info->argc; > const struct plugin_argument * const argv = plugin_info->argv; > bool enable = true; > > PASS_INFO(mark_noreturn, "optimized", 0, PASS_POS_INSERT_BEFORE); > > if (!plugin_default_version_check(version, &gcc_version)) { > error(G_("incompatible gcc/plugin versions")); > return 1; > } > > for (i = 0; i < argc; ++i) { > if (!strcmp(argv[i].key, "no-mark-noreturn")) { > enable = false; > continue; > } > error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, > argv[i].key); > } > > register_callback(plugin_name, PLUGIN_INFO, NULL, > &mark_noreturn_plugin_info); > > if (!enable) > return 0; > > #if BUILDING_GCC_VERSION < 6000 > register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, > &mark_noreturn_pass_info); > #endif > > return 0; > } > > Basically just create a __noreturn_function.foobarbaz alias to foobarbaz > function if that function is noreturn. Haven't investigated if all Linux > kernel arches will be happy with . in the name, other options are $ or > _ or conditionally one of them e.g. based on > NO_DOT_IN_LABEL/NO_DOLLAR_IN_LABEL > macros. > >> - Struct layout randomization (-frandomize-struct-layout) and debug info >> >> The GCC plugin hooks in a way that emitted debug info doesn't match with >> the >> resulting randomized structs. It works in clang because it generates DWARF >> later in the compilation process. >> >> References: >> >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84052 >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116457 >> >> Goal of the discussion: >> >> Determine how to best fix this in the plugin, or by using a different >> approach. The outcome of the discussion will then be used to continue the >> discussion with the clang/llvm and kernel hackers at LPC. >> >> - Userland stack unwinding from within the Linux kernel >> >> There are reasons for wanting to unwind both userland and kernel >> stacks from within the kernel. Currently the kernel can unwind kernel >> stacks based on ORC (which is revese-engineered from kernel compiled >> objects by objtool) and userland stacks provided stack frame pointers >> are present. SFrame is a format similar to ORC, but general enough to >> be used in userspace, and there is an on-going effort to introduce a >> SFrame based unwinder in the kernel. This will require some glibc >> support as well. >> >> References: >> >> First prototype (V1) from Josh Poimboeuf: >> https://lkml.kernel.org/lkml/cover.1699487758.git.jpoim...@kernel.org/ > > As discussed, either submit a patch to add another plugin callback event > after a new structure is almost ready to be finalized but debug info hasn't > been emitted yet, or there is also not so complicated option of reordering > the already registered debug info to match how the FIELD_DECLs have been > actually reordered. > > As for marking of the start and end of jump tables (though, of course, only > when they are actually emitted, switch lowering can use many different ways > of lowering the switches or combination thereof), I'd think a GCC plugin > registering an RTL pass which is run before "final" (or so), walks the > RTL and adds CODE_LABEL with some prefix and consecutively increased counter > before and after the JUMP_TABLE_DATA insns. > > Jakub