From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754299AbdEEMWs (ORCPT ); Fri, 5 May 2017 08:22:48 -0400 Received: from mx2.suse.de ([195.135.220.15]:46500 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752140AbdEEMWF (ORCPT ); Fri, 5 May 2017 08:22:05 -0400 From: Jiri Slaby To: akpm@linux-foundation.org Cc: torvalds@linux-foundation.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Jessica Yu , Rusty Russell Subject: [PATCH 4/7] DWARF: initialize structures for kernel and modules Date: Fri, 5 May 2017 14:21:57 +0200 Message-Id: <20170505122200.31436-4-jslaby@suse.cz> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170505122200.31436-1-jslaby@suse.cz> References: <20170505122200.31436-1-jslaby@suse.cz> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When booting, initialize eh_frame for use in the DWARF unwinder. Do the same for every coming module's info. And destroy the information when a module is going away. Signed-off-by: Jiri Slaby Cc: Jessica Yu Cc: Rusty Russell --- include/linux/module.h | 4 ++++ init/main.c | 3 +++ kernel/module.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/linux/module.h b/include/linux/module.h index 21f56393602f..21f7a23f8004 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -257,6 +257,7 @@ extern const typeof(name) __mod_##type##__##name##_device_table \ * files require multiple MODULE_FIRMWARE() specifiers */ #define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) +struct dwarf_table; struct notifier_block; #ifdef CONFIG_MODULES @@ -393,6 +394,9 @@ struct module { struct module_layout core_layout __module_layout_align; struct module_layout init_layout; + /* The handle returned from dwarf_add_table. */ + struct dwarf_table *dwarf_info; + /* Arch-specific module values */ struct mod_arch_specific arch; diff --git a/init/main.c b/init/main.c index cc48053bb39f..5acedeae355d 100644 --- a/init/main.c +++ b/init/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -490,6 +491,7 @@ asmlinkage __visible void __init start_kernel(void) char *command_line; char *after_dashes; + dwarf_init(); set_task_stack_end_magic(&init_task); smp_setup_processor_id(); debug_objects_early_init(); @@ -514,6 +516,7 @@ asmlinkage __visible void __init start_kernel(void) setup_arch(&command_line); mm_init_cpumask(&init_mm); setup_command_line(command_line); + dwarf_setup(); setup_nr_cpu_ids(); setup_per_cpu_areas(); boot_cpu_state_init(); diff --git a/kernel/module.c b/kernel/module.c index 4a3665f8f837..3571328e41fe 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -314,7 +315,7 @@ struct load_info { unsigned long mod_kallsyms_init_off; #endif struct { - unsigned int sym, str, mod, vers, info, pcpu; + unsigned int sym, str, mod, vers, info, pcpu, dwarf; } index; }; @@ -753,6 +754,27 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr) #endif /* CONFIG_SMP */ +static unsigned int find_dwarf(struct load_info *info) +{ + unsigned int section = 0; +#ifdef ARCH_DWARF_SECTION_NAME + section = find_sec(info, ARCH_DWARF_SECTION_NAME); + if (section) + info->sechdrs[section].sh_flags |= SHF_ALLOC; +#endif + return section; +} + +static void add_dwarf_table(struct module *mod, struct load_info *info) +{ + int index = info->index.dwarf; + + /* Size of section 0 is 0, so this is ok if there is no dwarf info. */ + mod->dwarf_info = dwarf_add_table(mod, + (void *)info->sechdrs[index].sh_addr, + info->sechdrs[index].sh_size); +} + #define MODINFO_ATTR(field) \ static void setup_modinfo_##field(struct module *mod, const char *s) \ { \ @@ -2133,6 +2155,8 @@ static void free_module(struct module *mod) /* Remove dynamic debug info */ ddebug_remove_module(mod->name); + dwarf_remove_table(mod->dwarf_info, false); + /* Arch-specific cleanup. */ module_arch_cleanup(mod); @@ -2970,6 +2994,8 @@ static struct module *setup_load_info(struct load_info *info, int flags) info->index.pcpu = find_pcpusec(info); + info->index.dwarf = find_dwarf(info); + /* Check module struct version now, before we try to use module. */ if (!check_modstruct_version(info->sechdrs, info->index.vers, mod)) return ERR_PTR(-ENOEXEC); @@ -3459,6 +3485,7 @@ static noinline int do_init_module(struct module *mod) /* Drop initial reference. */ module_put(mod); trim_init_extable(mod); + dwarf_remove_table(mod->dwarf_info, true); #ifdef CONFIG_KALLSYMS /* Switch to core kallsyms now init is done: kallsyms may be walking! */ rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); @@ -3734,6 +3761,9 @@ static int load_module(struct load_info *info, const char __user *uargs, goto sysfs_cleanup; } + /* Initialize dwarf table */ + add_dwarf_table(mod, info); + /* Get rid of temporary copy. */ free_copy(info); -- 2.12.2