In preparation for the objtool klp diff subcommand, define the entry size for the .static_call_sites section in its ELF header. This will allow tooling to extract individual entries.
Signed-off-by: Josh Poimboeuf <jpoim...@kernel.org> --- arch/x86/include/asm/static_call.h | 3 ++- include/linux/static_call.h | 6 ------ include/linux/static_call_types.h | 6 ++++++ kernel/bounds.c | 4 ++++ tools/include/linux/static_call_types.h | 6 ++++++ tools/objtool/check.c | 11 +++++++++-- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h index 41502bd2afd6..e03ad9bbbf59 100644 --- a/arch/x86/include/asm/static_call.h +++ b/arch/x86/include/asm/static_call.h @@ -58,7 +58,8 @@ ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0) #define ARCH_ADD_TRAMP_KEY(name) \ - asm(".pushsection .static_call_tramp_key, \"a\" \n" \ + asm(".pushsection .static_call_tramp_key, \"aM\", @progbits, " \ + __stringify(STATIC_CALL_TRAMP_KEY_SIZE) "\n" \ ".long " STATIC_CALL_TRAMP_STR(name) " - . \n" \ ".long " STATIC_CALL_KEY_STR(name) " - . \n" \ ".popsection \n") diff --git a/include/linux/static_call.h b/include/linux/static_call.h index 78a77a4ae0ea..5210612817f2 100644 --- a/include/linux/static_call.h +++ b/include/linux/static_call.h @@ -172,12 +172,6 @@ struct static_call_mod { struct static_call_site *sites; }; -/* For finding the key associated with a trampoline */ -struct static_call_tramp_key { - s32 tramp; - s32 key; -}; - extern void __static_call_update(struct static_call_key *key, void *tramp, void *func); extern int static_call_mod_init(struct module *mod); extern int static_call_text_reserved(void *start, void *end); diff --git a/include/linux/static_call_types.h b/include/linux/static_call_types.h index 5a00b8b2cf9f..eb772df625d4 100644 --- a/include/linux/static_call_types.h +++ b/include/linux/static_call_types.h @@ -34,6 +34,12 @@ struct static_call_site { s32 key; }; +/* For finding the key associated with a trampoline */ +struct static_call_tramp_key { + s32 tramp; + s32 key; +}; + #define DECLARE_STATIC_CALL(name, func) \ extern struct static_call_key STATIC_CALL_KEY(name); \ extern typeof(func) STATIC_CALL_TRAMP(name); diff --git a/kernel/bounds.c b/kernel/bounds.c index e4c7ded3dc48..21c37e3ea629 100644 --- a/kernel/bounds.c +++ b/kernel/bounds.c @@ -14,6 +14,7 @@ #include <linux/log2.h> #include <linux/spinlock_types.h> #include <linux/jump_label.h> +#include <linux/static_call_types.h> int main(void) { @@ -33,6 +34,9 @@ int main(void) #endif #if defined(CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE) && defined(CONFIG_JUMP_LABEL) DEFINE(JUMP_ENTRY_SIZE, sizeof(struct jump_entry)); +#endif +#ifdef CONFIG_HAVE_STATIC_CALL_INLINE + DEFINE(STATIC_CALL_TRAMP_KEY_SIZE, sizeof(struct static_call_tramp_key)); #endif /* End of constants */ diff --git a/tools/include/linux/static_call_types.h b/tools/include/linux/static_call_types.h index 5a00b8b2cf9f..eb772df625d4 100644 --- a/tools/include/linux/static_call_types.h +++ b/tools/include/linux/static_call_types.h @@ -34,6 +34,12 @@ struct static_call_site { s32 key; }; +/* For finding the key associated with a trampoline */ +struct static_call_tramp_key { + s32 tramp; + s32 key; +}; + #define DECLARE_STATIC_CALL(name, func) \ extern struct static_call_key STATIC_CALL_KEY(name); \ extern typeof(func) STATIC_CALL_TRAMP(name); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3afc748ba516..c3e1ca3dba06 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -650,8 +650,15 @@ static int create_static_call_sections(struct objtool_file *file) if (!sec) return -1; - /* Allow modules to modify the low bits of static_call_site::key */ - sec->sh.sh_flags |= SHF_WRITE; + /* + * Set SHF_MERGE to prevent tooling from stripping entsize. + * + * SHF_WRITE would also get set here to allow modules to modify the low + * bits of static_call_site::key, but the LLVM linker doesn't allow + * SHF_MERGE+SHF_WRITE for whatever reason. That gets fixed up by the + * makefiles with CONFIG_NEED_MODULE_PERMISSIONS_FIX. + */ + sec->sh.sh_flags |= SHF_MERGE; idx = 0; list_for_each_entry(insn, &file->static_call_list, call_node) { -- 2.49.0