aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrantisek Hrbata <fhrbata@redhat.com>2013-10-14 03:38:46 -0400
committerRusty Russell <rusty@rustcorp.com.au>2013-10-17 00:35:17 -0400
commiteb3057df732c304622aee77c450761746939a2dc (patch)
tree2890b26bb4827361e8ebc7835d2eaaac160179b8 /kernel
parenteed380f3f5933edb8f4c055ba34ae7908ed38565 (diff)
kernel: add support for init_array constructors
This adds the .init_array section as yet another section with constructors. This is needed because gcc could add __gcov_init calls to .init_array or .ctors section, depending on gcc (and binutils) version . v2: - reuse mod->ctors for .init_array section for modules, because gcc uses .ctors or .init_array, but not both at the same time v3: - fail to load if that does happen somehow. Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 947105fd4cab..5c9cf84017d5 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2708,7 +2708,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
2708 return 0; 2708 return 0;
2709} 2709}
2710 2710
2711static void find_module_sections(struct module *mod, struct load_info *info) 2711static int find_module_sections(struct module *mod, struct load_info *info)
2712{ 2712{
2713 mod->kp = section_objs(info, "__param", 2713 mod->kp = section_objs(info, "__param",
2714 sizeof(*mod->kp), &mod->num_kp); 2714 sizeof(*mod->kp), &mod->num_kp);
@@ -2738,6 +2738,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
2738#ifdef CONFIG_CONSTRUCTORS 2738#ifdef CONFIG_CONSTRUCTORS
2739 mod->ctors = section_objs(info, ".ctors", 2739 mod->ctors = section_objs(info, ".ctors",
2740 sizeof(*mod->ctors), &mod->num_ctors); 2740 sizeof(*mod->ctors), &mod->num_ctors);
2741 if (!mod->ctors)
2742 mod->ctors = section_objs(info, ".init_array",
2743 sizeof(*mod->ctors), &mod->num_ctors);
2744 else if (find_sec(info, ".init_array")) {
2745 /*
2746 * This shouldn't happen with same compiler and binutils
2747 * building all parts of the module.
2748 */
2749 printk(KERN_WARNING "%s: has both .ctors and .init_array.\n",
2750 mod->name);
2751 return -EINVAL;
2752 }
2741#endif 2753#endif
2742 2754
2743#ifdef CONFIG_TRACEPOINTS 2755#ifdef CONFIG_TRACEPOINTS
@@ -2776,6 +2788,8 @@ static void find_module_sections(struct module *mod, struct load_info *info)
2776 2788
2777 info->debug = section_objs(info, "__verbose", 2789 info->debug = section_objs(info, "__verbose",
2778 sizeof(*info->debug), &info->num_debug); 2790 sizeof(*info->debug), &info->num_debug);
2791
2792 return 0;
2779} 2793}
2780 2794
2781static int move_module(struct module *mod, struct load_info *info) 2795static int move_module(struct module *mod, struct load_info *info)
@@ -3233,7 +3247,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
3233 3247
3234 /* Now we've got everything in the final locations, we can 3248 /* Now we've got everything in the final locations, we can
3235 * find optional sections. */ 3249 * find optional sections. */
3236 find_module_sections(mod, info); 3250 err = find_module_sections(mod, info);
3251 if (err)
3252 goto free_unload;
3237 3253
3238 err = check_module_license_and_versions(mod); 3254 err = check_module_license_and_versions(mod);
3239 if (err) 3255 if (err)