aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/module.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/kernel/module.c b/kernel/module.c
index cabafe228444..f3cba93ea1e3 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -117,6 +117,8 @@ struct load_info {
117 char *secstrings, *strtab; 117 char *secstrings, *strtab;
118 unsigned long *strmap; 118 unsigned long *strmap;
119 unsigned long symoffs, stroffs; 119 unsigned long symoffs, stroffs;
120 struct _ddebug *debug;
121 unsigned int num_debug;
120 struct { 122 struct {
121 unsigned int sym, str, mod, vers, info, pcpu; 123 unsigned int sym, str, mod, vers, info, pcpu;
122 } index; 124 } index;
@@ -1993,7 +1995,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
1993 mod->core_size += bitmap_weight(info->strmap, strsect->sh_size); 1995 mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
1994} 1996}
1995 1997
1996static void add_kallsyms(struct module *mod, struct load_info *info) 1998static void add_kallsyms(struct module *mod, const struct load_info *info)
1997{ 1999{
1998 unsigned int i, ndst; 2000 unsigned int i, ndst;
1999 const Elf_Sym *src; 2001 const Elf_Sym *src;
@@ -2040,6 +2042,8 @@ static void add_kallsyms(struct module *mod, struct load_info *info)
2040 2042
2041static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num) 2043static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
2042{ 2044{
2045 if (!debug)
2046 return;
2043#ifdef CONFIG_DYNAMIC_DEBUG 2047#ifdef CONFIG_DYNAMIC_DEBUG
2044 if (ddebug_add_module(debug, num, debug->modname)) 2048 if (ddebug_add_module(debug, num, debug->modname))
2045 printk(KERN_ERR "dynamic debug error adding module: %s\n", 2049 printk(KERN_ERR "dynamic debug error adding module: %s\n",
@@ -2267,8 +2271,7 @@ static int check_modinfo(struct module *mod, struct load_info *info)
2267 return 0; 2271 return 0;
2268} 2272}
2269 2273
2270static void find_module_sections(struct module *mod, 2274static void find_module_sections(struct module *mod, struct load_info *info)
2271 const struct load_info *info)
2272{ 2275{
2273 mod->kp = section_objs(info, "__param", 2276 mod->kp = section_objs(info, "__param",
2274 sizeof(*mod->kp), &mod->num_kp); 2277 sizeof(*mod->kp), &mod->num_kp);
@@ -2323,9 +2326,15 @@ static void find_module_sections(struct module *mod,
2323 &mod->num_ftrace_callsites); 2326 &mod->num_ftrace_callsites);
2324#endif 2327#endif
2325 2328
2329 mod->extable = section_objs(info, "__ex_table",
2330 sizeof(*mod->extable), &mod->num_exentries);
2331
2326 if (section_addr(info, "__obsparm")) 2332 if (section_addr(info, "__obsparm"))
2327 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", 2333 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
2328 mod->name); 2334 mod->name);
2335
2336 info->debug = section_objs(info, "__verbose",
2337 sizeof(*info->debug), &info->num_debug);
2329} 2338}
2330 2339
2331static int move_module(struct module *mod, struct load_info *info) 2340static int move_module(struct module *mod, struct load_info *info)
@@ -2512,6 +2521,20 @@ static void module_deallocate(struct module *mod, struct load_info *info)
2512 module_free(mod, mod->module_core); 2521 module_free(mod, mod->module_core);
2513} 2522}
2514 2523
2524static int post_relocation(struct module *mod, const struct load_info *info)
2525{
2526 sort_extable(mod->extable, mod->extable + mod->num_exentries);
2527
2528 /* Copy relocated percpu area over. */
2529 percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
2530 info->sechdrs[info->index.pcpu].sh_size);
2531
2532 add_kallsyms(mod, info);
2533
2534 /* Arch-specific module finalizing. */
2535 return module_finalize(info->hdr, info->sechdrs, mod);
2536}
2537
2515/* Allocate and load the module: note that size of section 0 is always 2538/* Allocate and load the module: note that size of section 0 is always
2516 zero, and we rely on this for optional sections. */ 2539 zero, and we rely on this for optional sections. */
2517static noinline struct module *load_module(void __user *umod, 2540static noinline struct module *load_module(void __user *umod,
@@ -2521,8 +2544,6 @@ static noinline struct module *load_module(void __user *umod,
2521 struct load_info info = { NULL, }; 2544 struct load_info info = { NULL, };
2522 struct module *mod; 2545 struct module *mod;
2523 long err; 2546 long err;
2524 struct _ddebug *debug = NULL;
2525 unsigned int num_debug = 0;
2526 2547
2527 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", 2548 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
2528 umod, len, uargs); 2549 umod, len, uargs);
@@ -2564,22 +2585,7 @@ static noinline struct module *load_module(void __user *umod,
2564 if (err < 0) 2585 if (err < 0)
2565 goto free_modinfo; 2586 goto free_modinfo;
2566 2587
2567 /* Set up and sort exception table */ 2588 err = post_relocation(mod, &info);
2568 mod->extable = section_objs(&info, "__ex_table",
2569 sizeof(*mod->extable), &mod->num_exentries);
2570 sort_extable(mod->extable, mod->extable + mod->num_exentries);
2571
2572 /* Finally, copy percpu area over. */
2573 percpu_modcopy(mod, (void *)info.sechdrs[info.index.pcpu].sh_addr,
2574 info.sechdrs[info.index.pcpu].sh_size);
2575
2576 add_kallsyms(mod, &info);
2577
2578 if (!mod->taints)
2579 debug = section_objs(&info, "__verbose",
2580 sizeof(*debug), &num_debug);
2581
2582 err = module_finalize(info.hdr, info.sechdrs, mod);
2583 if (err < 0) 2589 if (err < 0)
2584 goto free_modinfo; 2590 goto free_modinfo;
2585 2591
@@ -2607,8 +2613,9 @@ static noinline struct module *load_module(void __user *umod,
2607 goto unlock; 2613 goto unlock;
2608 } 2614 }
2609 2615
2610 if (debug) 2616 /* This has to be done once we're sure module name is unique. */
2611 dynamic_debug_setup(debug, num_debug); 2617 if (!mod->taints)
2618 dynamic_debug_setup(info.debug, info.num_debug);
2612 2619
2613 /* Find duplicate symbols */ 2620 /* Find duplicate symbols */
2614 err = verify_export_symbols(mod); 2621 err = verify_export_symbols(mod);
@@ -2640,7 +2647,8 @@ static noinline struct module *load_module(void __user *umod,
2640 /* Unlink carefully: kallsyms could be walking list. */ 2647 /* Unlink carefully: kallsyms could be walking list. */
2641 list_del_rcu(&mod->list); 2648 list_del_rcu(&mod->list);
2642 ddebug: 2649 ddebug:
2643 dynamic_debug_remove(debug); 2650 if (!mod->taints)
2651 dynamic_debug_remove(info.debug);
2644 unlock: 2652 unlock:
2645 mutex_unlock(&module_mutex); 2653 mutex_unlock(&module_mutex);
2646 synchronize_sched(); 2654 synchronize_sched();