diff options
author | Frantisek Hrbata <fhrbata@redhat.com> | 2013-10-14 03:38:46 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-17 00:35:17 -0400 |
commit | eb3057df732c304622aee77c450761746939a2dc (patch) | |
tree | 2890b26bb4827361e8ebc7835d2eaaac160179b8 /kernel | |
parent | eed380f3f5933edb8f4c055ba34ae7908ed38565 (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.c | 20 |
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 | ||
2711 | static void find_module_sections(struct module *mod, struct load_info *info) | 2711 | static 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 | ||
2781 | static int move_module(struct module *mod, struct load_info *info) | 2795 | static 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) |